package cn.madog.utils;

import cn.madog.ui.FileBean;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HandleDoc {

    private File directory;
    private FileBean fileBean;

    // 文件名做第一路径
    private String baseDirectory;

    // 1 => A1, 2 => A2, 3 => A3/A4, 4 => B1
    private int type;

    public void handleFile(FileBean fileBean, File directory) {

        this.directory = directory;
        this.fileBean = fileBean;
        baseDirectory = fileBean.getName();

        try {
            FileInputStream fileInputStream = new FileInputStream(fileBean.getFile());

            fileBean.setMsg("");
            fileBean.setStatus(0);

            if (fileBean.getFile().getName().contains(".docx")) {
                handleDocx(fileInputStream);
            } else if (fileBean.getFile().getName().contains(".doc")) {
                handleDoc(fileInputStream);
            } else {
                fileBean.setStatus(2);
                System.out.println(">>>>>>>>>> " + fileBean.getName() + "处理失败了,不是doc或者docx <<<<<<<<<<<");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            fileBean.setStatus(2);
            fileBean.setMsg("该文档读取失败");
            System.out.println(">>>>>>>>>> " + fileBean.getName() + "处理失败了 <<<<<<<<<<<");
        }

    }

    private int continuousEmptyLine = 0;

    private String lastLine;

    // 什么篇
    private String Article;

    // 什么章
    private String chapter;

    // 什么节
    private String festival;

    // 当前章节要保存的路径
    private File saveLocation;

    // 题解析
    private String questionAnalysis;

    // 题干
    private String questionMain;

    // 题Id
    private String questionId;

    // 选项
    private HashMap<String, String> questionOption = null;

    // 答案
    private String questionAnswer;


    // 共用题干
    private String questionShareMain;

    // 共用题干的最后一题id
    private int questionShareMainId;

    // 共用题干开始的id
    private int questionShareStartId;

    // 下一行是不是共用题干
    private boolean isNextShareMain = false;

    // 上次执行的是否是解析
    private boolean isLastProcessAnalysis = false;

    private HashMap<String, QuestionInfo> questionInfoHashMap = new HashMap<>();

    private HashMap<String, List<QuestionInfo>> listHashMap = new HashMap<>();

    private void handleStream(String content) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new StringReader(content));

        String line = "";

        while ((line = bufferedReader.readLine()) != null) {
            // 为空不做处理，继续下次循环，不为空清除字符串中无用的空格，防止出错
            if (line == null || "".equals(line)) {
                // 防止忘记填写#end作为结尾标记，如果连续有5个以上的空行就视为结束
                if (lastLine == null || "".equals(lastLine)) {
                    continuousEmptyLine++;
                    lastLine = line;
                }
                continue;
            } else {
                continuousEmptyLine = 0;
            }

            try {
                if (continuousEmptyLine >= 5) {
                    saveFile(); // 保存最后一次读出来的题

                    // 设置处理状态
                    fileBean.setStatus(1);
                    // 文档读取完成，跳出循环，任务结束
                    break;

                } else if ("A1型题".equals(line)) {
                    type = 1;
                    continue;
                } else if ("A2型题".equals(line)) {
                    type = 2;
                    continue;
                } else if ("A3/A4型题".equals(line)) {
                    type = 3;
                    continue;
                } else if ("B1型题".equals(line)) {
                    type = 4;
                    continue;
                } else if (line.matches("^第.*篇\\s.*")) {
                    handleArticle(line);
                    continue;
                } else if (line.matches("^第.*章\\s.*")) {
                    handleChapter(line);
                    continue;
                } else if (line.matches("^第.*节\\s.*")) {
                    handleFestival(line);
                    continue;
                } else if (line.matches(".?\\d{1,3}～\\d{1,3}题共用题.*")) {
                    handleQuestionShareMain(line);
                    continue;
                } else if (isNextShareMain) {
                    handleShareMain(line);
                    continue;
                } else if (line.matches("^\\d{1,3}\\..*")) {
                    handleMain(line);
                    continue;
                } else if (line.matches("\\s*?[A-Ea-e].*")) {
                    handleOption(line);
                    continue;
                } else if (line.matches("^【答案】.*")) {
                    handleAnswer(line);
                    continue;
                } else if (line.matches("^【解析】.*")) {
                    handleAnalysis(line);
                    continue;
                } else if (isLastProcessAnalysis) {
                    handleLastAnalysis(line);
                    continue;
                }
            } catch (Exception e) {
                e.printStackTrace();
                fileBean.setStatus(2);
                fileBean.setMsg("大概错误位置：" + line);
                return;
            }
        }

        saveFile();
        fileBean.setStatus(1);
    }


    private void handleQuestionShareMain(String line) throws Exception {
        isNextShareMain = true;

        Pattern pattern = Pattern.compile("\\d{1,4}");

        Matcher matcher = pattern.matcher(line);
        matcher.find();

        questionShareStartId = Integer.parseInt(matcher.group());

        matcher.find();

        questionShareMainId = Integer.parseInt(matcher.group());
    }

    private void handleShareMain(String line) throws Exception {
        questionShareMain = line.replaceAll(" ", "");
        isNextShareMain = false;
    }

    private void handleOption(String line) throws Exception {
        String all = line.replaceAll(" ", "");
        String[] split = all.split("\\.");

        if (split.length >= 1) {

            StringBuffer stringBuffer = new StringBuffer();
            for (int i = 1; i < split.length; i++) {
                stringBuffer.append(split[i]).append(".");
            }
            stringBuffer.deleteCharAt(stringBuffer.length() - 1);

            questionOption.put(split[0], stringBuffer.toString());
        }
    }

    private void handleMain(String line) throws Exception {

        Pattern pattern = Pattern.compile("(?!\\d{1,4}|\\.).*");
        Matcher matcher = pattern.matcher(line);
        matcher.find();


        Pattern pattern1 = Pattern.compile("\\d{1,4}");
        Matcher matcher1 = pattern1.matcher(line);
        matcher1.find();
        questionId = matcher1.group();


//        if (type == 3) {
//            questionMain = questionShareMain + matcher.group();
//        } else {
            questionMain = matcher.group();
//        }

        questionOption = new HashMap<>();

        QuestionInfo questionInfo = new QuestionInfo(questionId, questionMain, questionOption, questionShareMain);
        if (type == 3) {
            questionInfo.setQuestionShareMain(questionShareMain);
        }
        questionInfoHashMap.put(questionId, questionInfo);
    }


    private void clearQuestionInfo() {
        questionOption = null;
        questionMain = null;
        questionId = null;
        questionAnalysis = null;
        questionAnswer = null;
    }

    private void handleAnswer(String line) throws Exception {

        if (type == 3) {

            Pattern pattern = Pattern.compile("\\d{1,4}\\.[A-Ea-e]");
            Matcher matcher = pattern.matcher(line);

            while (matcher.find()) {
                String group = matcher.group();
                String[] split = group.replaceAll(" ", "").split("\\.");
                if (split.length >= 1) {
                    String currentQuestionId = split[0];
                    QuestionInfo questionInfo = questionInfoHashMap.get(currentQuestionId);
                    if (questionInfo != null) {
                        questionInfo.setQuestionRightAnswer(split[1]);
                    }
                }
            }

        } else {
            String[] split = line.split("【答案】");
            if (split.length >= 1) {
                questionAnswer = split[1];
            }

            QuestionInfo questionInfo = questionInfoHashMap.get(questionId);
            if (questionInfo != null) {
                questionInfo.setQuestionRightAnswer(questionAnswer);
            }
        }
    }


    private void handleAnalysis(String line) throws Exception {
        String[] split = line.split("【解析】");
        if (split.length >= 1) {
            questionAnalysis = line.split("【解析】")[1];
        }

        if (type == 3) {

            int start = questionShareStartId;
            int end = questionShareMainId;

            while (start <= end) {
                QuestionInfo questionInfo = questionInfoHashMap.get(String.valueOf(start));
                if (questionInfo != null) {
                    questionInfo.setQuestionAnalysis(questionAnalysis);
                }
                start++;
            }
        } else {
            QuestionInfo questionInfo = questionInfoHashMap.get(questionId);
            if (questionInfo == null) {
                new QuestionInfo(questionId, questionMain, questionAnswer, questionAnalysis, questionOption);
            }
            questionInfo.setQuestionAnalysis(questionAnalysis);
            questionInfoHashMap.put(questionId, questionInfo);
        }

        isLastProcessAnalysis = true;
        clearQuestionInfo();
    }


    private void handleLastAnalysis(String line) {
        if (type == 3) {
            int start = questionShareStartId;
            int end = questionShareMainId;

            while (start <= end) {
                QuestionInfo questionInfo = questionInfoHashMap.get(String.valueOf(start));
                if (questionInfo != null) {
                    questionInfo.setQuestionAnalysis(questionInfo.getQuestionAnalysis() + line);
                }
                start++;
            }
        } else {
            QuestionInfo questionInfo = questionInfoHashMap.get(questionId);
            if (questionInfo != null) {
                questionInfo.setQuestionAnalysis(questionInfo.getQuestionAnalysis() + line);
            }
        }

        isLastProcessAnalysis = false;
    }


    private void saveFile() {


        if (questionInfoHashMap.isEmpty()) {
            return;
        }

        if (type == 3) {

            HashMap<String, List<QuestionInfo>> hashMap = new HashMap<>();

            String shareMain = "";

            List<QuestionInfo> questionInfos = null;

            for (QuestionInfo value : questionInfoHashMap.values()) {

                if (!shareMain.equals(value.getQuestionShareMain())) {

                    if (questionInfos != null) {
                        hashMap.put(shareMain, questionInfos);
                    }
                    questionInfos = null;
                    questionInfos = new ArrayList<>();
                }

                questionInfos.add(value);

                shareMain = value.getQuestionShareMain();
            }

            hashMap.put(shareMain, questionInfos);

            XSSFWorkbook workbook = ExcelExportUtils.exportA3(hashMap);
            write(workbook);

        } else {
            ArrayList<QuestionInfo> questionInfos = new ArrayList<>(questionInfoHashMap.values());
            XSSFWorkbook workbook = ExcelExportUtils.export(questionInfos);
            write(workbook);
        }


//        questionInfoHashMap.forEach((s, questionInfo) -> {
//            System.out.println("questionId = " + s + ", questionInfo = " + questionInfo.toString());
//        });

        questionInfoHashMap.clear();
    }

    private void write(XSSFWorkbook workbook) {
        try {

            StringBuffer path = new StringBuffer();
            path.append(directory.getPath() + "/" + baseDirectory.split("\\.")[0] + "/" );
            if (Article != null && !"".equals(Article)){
                path.append(Article).append("/");
//                Article = null;
            }

            if (chapter != null && !"".equals(chapter)){
                path.append(chapter).append("/");
//                chapter = null;
            }

            if (festival != null && !"".equals(festival)){
                path.append(festival);
                festival = null;
            }


            System.out.println(path.toString());

            saveLocation = new File(path.toString());
            if (!saveLocation.exists()) {
                saveLocation.mkdirs();
            }

            workbook.write(new FileOutputStream(saveLocation.getPath() + "/" +  saveLocation.getName() + ".xlsx"));
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("======================== 创建excel文件失败了");
        }
    }

    private void handleFestival(String line) {
        // 不为空的时候表示有一章读取完成了，保存到当前篇目录下
        if (festival != null || !"".equals(festival)) {
            // TODO 保存一次文件
            saveFile();
        }

        String[] strings = line.replaceAll(" ", "").split("节");
        if (strings.length > 1) {
            festival = strings[strings.length - 1];

//            saveLocation = new File(saveLocation.getPath() + "/" + festival);
//            if (!saveLocation.exists()) {
//                saveLocation.mkdirs();
//            }
        }
    }

    private void handleArticle(String line) {
        // 不为空的时候表示有一章读取完成了，保存到当前篇目录下
        if (Article != null && !"".equals(Article)) {
            // TODO 保存一次文件
            saveFile();
        }

        String[] strings = line.replaceAll(" ", "").split("篇");
        if (strings.length > 1) {
            Article = strings[strings.length - 1];
//            File file = new File(directory.getPath() + "/" + baseDirectory.split("\\.")[0] + "/" + Article);
//            if (!file.exists()) {
//                file.mkdirs();
//            }
        }
    }

    private void handleChapter(String line) {

        // 不为空的时候表示有一章读取完成了，保存到当前篇目录下
        if (chapter != null && !"".equals(chapter)) {
            // TODO 保存一次文件
            saveFile();
        }

        String[] strings = line.replaceAll(" ", "").split("章");
        if (strings.length > 1) {
            chapter = strings[strings.length - 1];

//            saveLocation = new File(directory.getPath() + "/" + baseDirectory.split("\\.")[0] + "/" + Article + "/" + chapter);
//            if (!saveLocation.exists()) {
//                saveLocation.mkdirs();
//            }
        }
    }

    private void handleDoc(FileInputStream inputStream) {
        try {
            HWPFDocument hwpfDocument = new HWPFDocument(inputStream);
            WordExtractor extractor = new WordExtractor(hwpfDocument);
            handleStream(extractor.getText());

        } catch (IOException e) {
            e.printStackTrace();
            fileBean.setStatus(2);
            System.out.println(">>>>>>>>>> 加载Document时失败 <<<<<<<<<<<");
        }
    }

    private void handleDocx(FileInputStream inputStream) {
        try {
            XWPFDocument xwpfDocument = new XWPFDocument(inputStream);

            XWPFWordExtractor extractor = new XWPFWordExtractor(xwpfDocument);

            handleStream(extractor.getText());

        } catch (IOException e) {
            e.printStackTrace();
            fileBean.setStatus(2);
            System.out.println(">>>>>>>>>> 加载Document时失败 <<<<<<<<<<<");
        }
    }
}
